﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Linq;
using System.Reflection;
using System.IO;
using System.Security.Cryptography;
using System.Collections;
using System.ComponentModel;
using System.Collections.ObjectModel;
using Oroboros;
using Oroboros.Objects;
using Oroboros.Save_Data;

namespace Save_Editor
{
    /// <summary>
    /// Extends Oroboros for cheating purposes
    /// </summary>
    public static class Cheats
    {
        /// <summary>
        /// Remove a Build Defence task
        /// </summary>
        /// <param name="tasks"></param>
        /// <param name="Guid"></param>
        public static void RemoveDefence(this ObservableCollection<TaskSaveData> tasks, Guid Guid)
        {
            do
            {
                for (int i = 0; i < tasks.Count; i++)
                {
                    if (tasks[i] is DefenceTaskSaveData)
                    {
                        if ((tasks[i] as DefenceTaskSaveData).Defence == Guid)
                        {
                            tasks.RemoveAt(i);
                            break;
                        }
                    }
                }
            }
            while (tasks.ContainsDefence(Guid));
        }

        public static bool ContainsDefence(this ObservableCollection<TaskSaveData> tasks, Guid DefenceGuid)
        {
            foreach (TaskSaveData task in tasks)
            {
                if (task is DefenceTaskSaveData)
                {
                    if ((task as DefenceTaskSaveData).Defence == DefenceGuid)
                        return true;
                }
            }
            return false;
        }

        public static void MaxItems(this InventorySaveData inventory)
        {
            inventory.GridHeight = 128;
            inventory.GridWidth = 16;
            foreach (ItemSaveData item in inventory.Items)
            {
                if (item.FoodUnits != 0)
                    item.FoodUnits = 999;
                if (item.FuelUnits != 0)
                    item.FuelUnits = 999;
                if (item.MedicineUnits != 0)
                    item.MedicineUnits = 999;
                if (item is AmmoBoxItemSaveData)
                    (item as AmmoBoxItemSaveData).NumRounds = int.MaxValue;
                if (item is GunItemSaveData)
                    (item as GunItemSaveData).NumRounds = int.MaxValue;
            }
        }

        public static void MaxStats(this ObservableCollection<HumanSaveData> humans)
        {
            foreach (HumanSaveData human in humans)
            {
                human.CurrentStats.MaxStats();
            }
        }

        public static void MaxSkills(this ObservableCollection<HumanSaveData> humans)
        {
            foreach (HumanSaveData human in humans)
            {
                human.Skills.MaxSkills();
            }
        }

        public static void MaxHealth(this ObservableCollection<HumanSaveData> humans)
        {
            foreach (HumanSaveData human in humans)
            {
                human.Health.MaxHealth();
                human.MoraleRating = 100;
            }
        }

        public static void MaxItems(this ObservableCollection<HumanSaveData> humans)
        {
            foreach (HumanSaveData human in humans)
            {
                human.Inventory.MaxItems();
            }
        }

        public static void MaxSkills(this ObservableCollection<SkillSaveData> skills)
        {
            foreach (SkillSaveData skill in skills)
            {
                skill.DailySuccessCount += 100;
                skill.Level = 100;
                if (skill is UmbrellaSkillSaveData)
                {
                    (skill as UmbrellaSkillSaveData).Experience += 100;
                }
            }
        }

        public static void MaxHealth(this HealthSaveData health)
        {
            health.LeftArm = (int)(0.5 * health.Toughness);
            health.RightArm = (int)(0.5 * health.Toughness);
            health.Torso = (int)(1 * health.Toughness);
            health.Head = (int)(0.2 * health.Toughness);
            health.Legs = (int)(0.7 * health.Toughness);

            health.BonusToughness = health.Toughness;
            health.BonusLeftArm = health.Toughness;
            health.BonusRightArm = health.Toughness;
            health.BonusTorso = health.Toughness;
            health.BonusHead = health.Toughness;
            health.BonusLegs = health.Toughness;
        }

        public static void MaxStats(this CharacterStatsSaveData stats)
        {
            stats.Smarts = 100;
            stats.Speed = 100;
            stats.Finesse = 100;
            stats.Power = 100;
            stats.Toughness = 100;
        }

        public static bool HasGuid(this ObservableCollection<ItemSaveData> items, ItemSaveData ItemToAdd)
        {
            foreach (ItemSaveData item in items)
            {
                if (item.Guid == ItemToAdd.Guid)
                {
                    return true;
                }
            }
            return false;
        }

        public static void Add(this ObservableCollection<ItemSaveData> items, ItemSaveData item, bool safe)
        {
            int ran = 0;
            while (item.Guid == Guid.Empty || items.HasGuid(item))
            {
                item.Guid = Guid.NewGuid();
                ran++;
            }
            items.Add(item);
        }
    }
}